#include <bits/stdc++.h>

using ll = int64_t; // 定义长整型
using std::cin, std::cout;

// 常量定义
const ll maxn = 5e4 + 5;           // 最大节点数
const ll inf = (ll(1) << 60);      // 无穷大，用于初始最小值

ll n, m;                           // 节点数和赛道数
ll mins = inf;                     // 道路的最小长度初始化为无穷大
ll maxs = 0;                       // 道路总长度初始化为0
ll g[maxn], f[maxn];               // g[u]：当前节点u向上传递的最长路径长度
                                    // f[u]：当前节点u子树中形成的赛道数
std::vector<std::pair<ll, ll>> adj[maxn]; // 邻接表存储树结构，pair形式为（邻接节点, 道路长度）

/**
 * @brief 深度优先搜索，用于计算在给定的最小赛道长度num下，可以形成多少条满足条件的赛道。
 * @param fth 当前节点的父节点
 * @param u 当前访问的节点
 * @param num 当前尝试的最小赛道长度
 */
void dfs(ll fth, ll u, const ll& num){
    std::multiset<ll> ms; // 存储当前节点所有子路径的部分长度

    // 遍历当前节点的所有邻接节点
    for(auto [v, w] : adj[u]){
        if(fth == v) continue; // 避免回到父节点

        dfs(u, v, num);       // 递归遍历子节点
        f[u] += f[v];         // 累加子节点已经形成的赛道数

        ll ff = g[v] + w;     // 计算从子节点v向上传递的路径长度
        if(ff >= num){
            ++f[u];            // 该路径长度已满足至少为num，可以形成一条赛道
        }
        else{
            ms.emplace(ff);    // 不足，则记录下来，尝试与其他路径组合
        }
    }

    // 如果没有残余的部分路径，不需要处理
    if(ms.empty()) return;

    if(ms.size() == 1){
        // 只有一个残余路径，无法与其他路径组合，直接传递
        g[u] = *ms.begin();
        return;
    }

    ll ans = -1; // 记录无法组合的路径长度
    ll nans;

    while(ms.size() >= 2){
        nans = *ms.begin();      // 取出最小的部分路径
        ms.erase(ms.begin());    // 移除该部分

        // 尝试在剩余的部分路径中找到一个，使得两者之和 >= num
        // 即寻找 >= (num - nans) 的最小值
        auto fit = ms.lower_bound(num - nans);
        if(fit == ms.end()){
            // 没有找到满足条件的路径，记录当前的nans
            ans = nans;
        }
        else{
            // 找到了一个可以与nans组合形成一条赛道
            f[u]++;                 // 增加一个赛道
            ms.erase(fit);          // 移除该路径，避免重用
        }
    }

    // 处理剩余的一个路径
    if(ms.size() > 0){
        g[u] = *std::prev(ms.end()); // 传递最大的剩余路径
    }
    else if(ans != -1){
        g[u] = ans; // 传递无法组合的路径
    }
}

/**
 * @brief 检查在最小赛道长度为num的情况下，是否可以形成至少m条赛道。
 * @param num 当前尝试的最小赛道长度
 * @return 如果可以形成至少m条赛道，则返回true；否则返回false
 */
bool check(ll num){
    std::fill(f, f + 1 + n, 0); // 初始化赛道计数
    std::fill(g, g + 1 + n, 0); // 初始化路径长度
    dfs(0, 1, num);              // 从根节点1开始DFS
    return f[1] >= m;             // 判断总赛道数是否满足
}

int main(){
    // 优化输入输出速度
    std::iostream::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n >> m; // 读取节点数和赛道数

    // 读取n-1条道路，并构建邻接表
    for(ll i = 1; i < n; i++){
        ll u, v, w;
        cin >> u >> v >> w;
        mins = std::min(mins, w); // 更新道路最小长度
        maxs += w;                 // 计算所有道路的总长度
        adj[u].emplace_back(v, w);
        adj[v].emplace_back(u, w);
    }

    ll l = mins, r = maxs; // 初始化二分查找的左右边界
    ll ans = l;             // 初始答案设为最小道路长度
    ll mid;

    // 二分查找，寻找满足条件的最大最小赛道长度
    while(l <= r){
        mid = (l + r) / 2;
        if(check(mid)){
            ans = mid; // 如果可以满足，尝试更大的mid
            l = mid + 1;
        }
        else{
            r = mid - 1; // 否则，缩小mid
        }
    }

    cout << ans << '\n'; // 输出最终答案
}
